// sunday 15aug.2010 - looks like the solution for versioning and duplicates naming conventions
// needs some adjustment when using zipped resources as the last date modified attribute maybe off by
// either 2 or 4 seconds dues to m/s windows bug
import java.io.*;
import java.nio.channels.*;
public class HarvesterHelper
{
    def fs = System.getProperty('file.separator')
    def pn = 'harvester.properties'
    def config 
    def suffix
    boolean d = false
    boolean v = false
    int i
    int j
    File fo
    def donorpath
    def targetpath
    def dup=0
    def ver=0

// class constructor loads configuration properties and sets internal variables to their values
public HarvesterHelper
{
    File fp = new File(pn)
    if (fp.exists())
    {
        config = new ConfigSlurper().parse(fp.toURL())
    } // end of if to load properties

    donorpath = config.path.to.source        // path to read from
    targetpath = config.path.to.target        // vaultOutputPath

    donorpath = (donorpath.endsWith(fs)) ? donorpath : donorpath + fs ;
    targetpath = (targetpath.endsWith(fs)) ? targetpath : targetpath + fs ;
} // end of constructor

// =========================================================
// closures

// closure using new java io processes rather than ant copy
def localcopy = {fi, ou ->
        FileChannel inChannel 
        FileChannel outChannel

        try 
        {
            inChannel = new FileInputStream(fi).getChannel();
            outChannel = new FileOutputStream(ou).getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } 

        catch (IOException e) 
        {
            println "localcopy:"+e.message
            throw e;
        }

        finally 
        {
            if (inChannel != null) 
            {
                inChannel.close();
            } // end of if
            
            if (outChannel != null) 
            {
                outChannel.close();
	        Date lastModified = new Date(fi.lastModified())
    		boolean blnSuccess = ou.setLastModified(lastModified.getTime());
            } // end of if
        } // end of finally
} // end of closure

// return a string like dup1, dup2, etc to be used as a component in new resource name like abc.dup1.txt
def getDup(v,d)  
{ 
    def dtx = (v) ? "" : "."
    dtx += (d) ? "dup$dup" : ""
    return dtx
} // end of getDup

// turn on duplicate component generator
def setDup(){ ++dup; d=true; }
def isDup(){ return d; }

// turn on versioning component generator
def getVer(v,ver) {if (v) return ".ver$ver" else return "";}
def setVer = { ++ver; v=true; }

// f is input file handle; fno is output resource name string; fsize tells how many bytes in input resource file handle; fdate is a long seconds parm of f's lastmodified date
def getName = 
{ f, fno, fsize, fdate ->
    fo = new File(fno)
    
    // when new resource does not exist in target folder, just use same name without ver/dup
    if (!fo.exists()) return fno

    // prepare loop variables and turn off duplicates and versioning feature
    def flag = true
    def ver = 0
    v = false
    dup = 0
    d = false
    def s
    int j = fno.lastIndexOf(".")
    // get resource suffix like .jpg or something ending with a period
    suffix = fno.toString().substring(j)

    /*
        resources with identical attributes like size and date are just duplicates and given a 'dup1' component in the output resource name
        but if either attribute is not identical, then resources with the same name are treated as versions of the same thing; of course this may be completely wrong if different data has the has same name
    */
    while (flag)
    {
	    // first-time thru do not apply 'ver' if same attributes just make it a 'dup'
        if (v) {++ver}        
        s = fno.substring(0,j)+getVer(v,ver)+suffix  
        def f3 = new File(s)
        if (f3.exists())
        {
        
            println "HarvestHelper: ${f.toString()}=${fdate} sec.s"
            println "             : ${f3.toString()}=${f3.lastModified()} sec.s"
            def diff = fdate - f3.lastModified()
            
            // if theres less than a second diff between resource, then we treat them as same
            def samedate = (diff>-4001&&diff<4001) ? true : false

            println "        diff : ${diff}  and samedate=$samedate"


            // f.lastModified().equals(f3.lastModified())
            if (fsize==f3.size()&&samedate)
            {
                def flag2 = true
                while (flag2)
                {
                    setDup()
                    s = fno.substring(0,j)+getVer(v,ver)+getDup(v,d)+suffix
                    f3 = new File(s)
                    if (!f3.exists())
                    {
                        flag = false            // exit the outer while loop
                        flag2 = false            // exit the inner while
                    } // end of if
                }  // end of while
            } // end of if
            else
            {
		// treat as a version of the original
                v = true
            } // end of else
        } // end of if

        else
        {
            flag = false
        } // end of else

    } // end of while
    
    return s    
} // end of get

// --------------------- end of closures -----------------------

  public static void main(String... args)
  {
    println "--- start of job ----"
    HarvesterHelper hh = new HarvesterHelper()
    def fn1 = hh.donorpath+"xml.groovy"
    File f = new File(fn1)

    def fn2 = hh.targetpath+"xml.groovy"
    println "fn2 starts with = $fn2"
    fn2 = hh.getName(f, fn2, f.size(), f.lastModified())
    println "getName($fn2) returned a name of "+fn2

    File f2 = new File(fn2)
    hh.localcopy(f,f2)
    println "ended with fn2=$fn2"
    println "--- end of job ----"
  } // end of main

} // end of class    
    
    
    
